import math
from datetime import datetime
import codecs
from flask_wtf.file import FileRequired, FileAllowed

from app.libs.ParseDocx import ParseDocx, ParseDoc, ParsePDF
from app.config.secure import DOC_PATH, SELFDOC_PATH
from app.libs.token_auth import parseToken
from app.models.aigc_order_info import aigc_order_info
from app.models.order_info import order_info
from app.models.user import User
from app.models.writer_orders import writer_orders
from app.models.wxpay_order import wxpay_order
from app.taobao_api.get_order_status import Order_Status
from app.validators.base import BaseForm as Form, SearchForm
from wtforms import StringField, IntegerField, FloatField, FieldList, DecimalField, TextAreaField, FileField
from wtforms.validators import length, DataRequired, Length, NumberRange
from wtforms import ValidationError
from flask import g
import re
from app.taobao_api import config, get_order_status
from app import redisclient
from app.validators.filebase import FileBaseForm
from app.libs.tools import count_char_sum, flaot2Decimal


class ArticleSubmitForm(Form):
    title = StringField(default='')
    author = StringField(default='佚名', validators=[length(min=0, max=48, message='作者长度不能超过50字')])
    content = TextAreaField(default='')
    order_number = StringField(default='')
    chars_sum = IntegerField()
    sum = IntegerField()
    taobao_orders = []
    domain = StringField(default='')
    free = IntegerField(default=0)
    file_path = StringField(default='')
    selffileList = FieldList(StringField(), default=[])
    checkmodel = IntegerField(default=2)
    token = StringField(default='')
    uid = IntegerField(default=0)
    check_aigc = IntegerField(default=0)

    def validate_checkmodel(self, field):
        if len(self.title.data) > 300:
            raise ValidationError('标题字数不超过300字')
        if field.data == 2:
            if self.token.data and self.token.data != '':
                self.uid.data = parseToken(self.token.data)
            if self.content.data == '':
                raise ValidationError('没有获取到内容，请重新提交')
            if self.chars_sum.data == 0:
                self.chars_sum.data = count_char_sum(self.content.data)
            unit = int(redisclient.getunit(self.domain.data))
            sum = math.floor(int(self.chars_sum.data) / unit)
            if sum == 0:
                sum = 1
            self.sum.data = sum
            pattern = '^\d{18,19}(,\d{18,19})*'
            if not re.fullmatch(pattern, self.order_number.data):
                raise ValidationError('订单号格式不正确,应为18或19位数字,不可包含空格,若有多个订单请用英文逗号分隔!')
            secret = redisclient.getAppSecret(self.domain.data) if self.domain.data != '' else redisclient.getAppSecret(
                'check')            
            #secret = 'TbAldszyw2zfa35ttemzxhbh2zkx27x6mabxssreswt2vkxgxt'
            self.taobao_orders = self.order_number.data.split(',') if ',' in self.order_number.data else [
                self.order_number.data]
            if len(set(self.taobao_orders)) != len(self.taobao_orders):
                raise ValidationError('请不要重复输入相同订单号哦。')
            order_status = Order_Status(self.order_number.data, self.sum.data, secret, self.chars_sum.data)
            order_status.validate_order_number('text_check')
        if field.data == 1:
            if self.token.data and self.token.data != '':
                self.uid.data = parseToken(self.token.data)
                self.taobao_orders = ['selfdata_free_check']
                if self.content.data == '':
                    raise ValidationError('没有获取到内容，请重新提交')
            else:
                raise ValidationError('自建库查重请先点击右上角扫码登录')


class ArticleSubmitByUploadForm(Form):
    title = StringField(default='')
    author = StringField(default='佚名', validators=[length(min=0, max=48, message='作者长度不能超过50字')])
    content = TextAreaField(default='')
    order_number = StringField()
    chars_sum = IntegerField()
    sum = IntegerField()
    taobao_orders = []
    paytype = StringField(default='taobao')
    out_trade_no = StringField(default='')
    file_path = StringField(default='')
    amount = DecimalField()

    def __init__(self, g):
        super(ArticleSubmitByUploadForm, self).__init__()
        self.uid = g.user.uid

    def caculateOrderCount(self, unit):
        user_info = User.query.filter_by(id=self.uid).first()
        free_chars = user_info.free_chars
        if free_chars == -1:
            return 0
        if free_chars >= self.chars_sum.data:
            return 0
        sum = math.floor((int(self.chars_sum.data) - free_chars) / unit)
        if sum == 0:
            sum = 1
        return sum

    def caculateAmount(self, unit):
        price = redisclient.getRepetitionPrice()
        user_info = User.query.filter_by(id=self.uid).first()
        free_chars = user_info.free_chars
        if free_chars == -1:
            return 0
        if free_chars >= self.chars_sum.data:
            return 0
        amount = math.floor((int(self.chars_sum.data) - free_chars) / unit) * price
        if amount == 0:
            amount = price
        self.amount.data = amount
        pay_amount = flaot2Decimal(amount) - user_info.amount
        if pay_amount <= 0:
            return 0
        return pay_amount

    #
    def validate_paytype(self, field):
        if self.content.data == '':
            raise ValidationError('没有获取到内容，请重新提交')
        if self.chars_sum.data == 0:
            self.chars_sum.data = len(self.content.data)
        unit = 1000
        self.sum.data = self.caculateOrderCount(unit)
        need_pay_amount = self.caculateAmount(unit)
        if self.author.data == '':
            self.author.data = '佚名'
        if self.sum.data == 0:
            self.taobao_orders = ['wx_free_account']
            self.amount.data = 0
            self.paytype.data = 'free_chars'
            current_report = order_info.query.filter_by(user=self.uid).filter_by(completed=0).all()
            if len(current_report) > 0:
                raise ValidationError('有待完成的查重报告，请完成后再提交')
        else:
            if field.data == 'taobao':
                pattern = '^\d{18,19}(,\d{18,19})*'
                if not re.fullmatch(pattern, self.order_number.data):
                    raise ValidationError(
                        '订单号格式不正确,应为18或19位数字,不可包含空格,若有多个订单请用英文逗号分隔!')
                self.taobao_orders = self.order_number.data.split(',') if ',' in self.order_number.data else [self.order_number.data]
                if len(set(self.taobao_orders)) != len(self.taobao_orders):
                    raise ValidationError('请不要重复输入相同订单号哦。')
                order_status = Order_Status(self.order_number.data, self.sum.data,
                                            'TbAldszyw2zfa35ttemzxhbh2zkx27x6mabxssreswt2vkxgxt',
                                            self.chars_sum.data)
                isvalid = order_status.validate_order_number('text_check')
            if field.data == 'wxpay':
                pay_amount = self.caculateAmount(1000)
                wxpay_info = wxpay_order.query.filter_by(out_trade_no=self.out_trade_no.data).first()
                if wxpay_info.total_amount <= pay_amount:
                    raise ValidationError('支付金额错误，请重新提交')
            if field.data == 'balance':
                if need_pay_amount > 0:
                    raise ValidationError('提交错误，账户余额不足，请重新上传提交')


class ArticleSubmitByPasteForm(Form):
    title = StringField(default='')
    author = StringField(default='佚名', validators=[length(min=0, max=48, message='作者长度不能超过50字')])
    content = TextAreaField(default='')
    order_number = StringField()
    chars_sum = IntegerField()
    sum = IntegerField()
    taobao_orders = []
    paytype = StringField(default='taobao')
    amount = DecimalField()
    out_trade_no = StringField(default='')


    def __init__(self, g):
        super(ArticleSubmitByPasteForm, self).__init__()
        self.uid = g.user.uid

    def caculateOrderCount(self, unit):
        user_info = User.query.filter_by(id=self.uid).first()
        free_chars = user_info.free_chars
        if free_chars == -1:
            return 0
        if free_chars >= self.chars_sum.data:
            return 0
        sum = math.floor((int(self.chars_sum.data) - free_chars) / unit)
        if sum == 0:
            sum = 1
        return sum

    def caculateAmount(self, unit):
        price = redisclient.getRepetitionPrice()
        user_info = User.query.filter_by(id=self.uid).first()
        free_chars = user_info.free_chars
        if free_chars == -1:
            return 0
        if free_chars >= self.chars_sum.data:
            return 0
        amount = math.floor((int(self.chars_sum.data) - free_chars) / unit) * price
        if amount == 0:
            amount = price
        self.amount.data = amount
        pay_amount = flaot2Decimal(amount) - user_info.amount
        if pay_amount <= 0:
            return 0
        return pay_amount

    def validate_paytype(self, field):
        if self.content.data == '':
            raise ValidationError('没有获取到内容，请重新提交')
        if self.chars_sum.data == 0:
            self.chars_sum.data = len(self.content.data)
        unit = 1000
        self.sum.data = self.caculateOrderCount(unit)
        need_pay_amount = self.caculateAmount(unit)
        if self.author.data == '':
            self.author.data = '佚名'
        if self.sum.data == 0:
            self.taobao_orders = ['wx_free_account']
            self.amount.data = 0
            self.paytype.data = 'free_chars'
            current_report = order_info.query.filter_by(user=self.uid).filter_by(completed=0).all()
            if len(current_report) > 0:
                raise ValidationError('有待完成的查重报告，请完成后再提交')
        else:
            if field.data == 'taobao':
                pattern = '^\d{18,19}(,\d{18,19})*'
                if not re.fullmatch(pattern, self.order_number.data):
                    raise ValidationError(
                        '订单号格式不正确,应为18或19位数字,不可包含空格,若有多个订单请用英文逗号分隔!')
                self.taobao_orders = self.order_number.data.split(',') if ',' in self.order_number.data else [self.order_number.data]
                if len(set(self.taobao_orders)) != len(self.taobao_orders):
                    raise ValidationError('请不要重复输入相同订单号哦。')
                order_status = Order_Status(self.order_number.data, self.sum.data,
                                            'TbAldszyw2zfa35ttemzxhbh2zkx27x6mabxssreswt2vkxgxt',
                                            self.chars_sum.data)
                isvalid = order_status.validate_order_number('text_check')
            else:
                if field.data == 'wxpay':
                    pay_amount = self.caculateAmount(1000)
                    wxpay_info = wxpay_order.query.filter_by(out_trade_no=self.out_trade_no.data).first()
                    if wxpay_info.total_amount <= pay_amount:
                        raise ValidationError('支付金额错误，请重新提交')
                if field.data == 'balance':
                    if need_pay_amount > 0:
                        raise ValidationError('提交错误，账户余额不足，请重新上传提交')
    #
    # def validate_checkmodel(self, field):
    #     if field.data == 1 and self.selffileList.data == []:
    #         raise ValidationError('自建库查重请先上传相应文档！')


class ArticleBatchSubmitForm(Form):
    title = StringField(default='')
    author = StringField(default='佚名', validators=[length(min=0, max=48, message='作者长度不能超过50字')])
    content = TextAreaField(default='')


class ReArticleSubmitForm(Form):
    order_number = StringField()


class WriterArticleSubmitForm(Form):
    title = StringField(default='')
    author = StringField(default='佚名', validators=[length(min=0, max=48, message='作者长度不能超过50字')])
    content = TextAreaField(default='')
    chars_sum = IntegerField()
    order_number = StringField()

    def validate_order_number(self, field):
        unfinished = order_info.query.filter_by(taobao_orders=field.data).filter_by(completed=0).first()
        if unfinished:
            raise ValidationError('您存在正在进行的查重任务,请稍后提交')


class DocUploadForm(FileBaseForm):
    file = FileField('file', validators=[FileRequired(message='请选择文件上传'),
                                         FileAllowed(['docx', 'doc'], message='仅允许上传docx,doc格式文件！'),
                                         ])
    content = StringField()
    filePath = StringField()
    char_sum = StringField()
    showfilename = StringField()

    def __init__(self, g):
        super(DocUploadForm, self).__init__()
        self.uid = g.user.uid

    def validate_file(self, field):
        file_name = field.data.filename.replace('+', '')
        timestamp = str(int(datetime.now().timestamp()))
        localPath = DOC_PATH + timestamp + '_' + file_name
        self.filePath.data = localPath
        field.data.save(localPath)
        if '.pdf' in file_name:
            char_sum, content = ParsePDF(timestamp + '_' + file_name)
        else:
            char_sum, content = ParseDoc(timestamp + '_' + file_name)
        self.char_sum.data = self.clean_content_count(content)
        self.content.data = self.clean_content(content)
        if self.content.data == '':
            raise ValidationError('doc文档读取失败，可能文件损坏，请检查后重新上传！')
        if len(self.content.data) < 100:
            raise ValidationError('字数不足100！不可检测')
        if len(self.content.data) > 300000:
            raise ValidationError('单次检测上限30万字，请修改或分批上传')

    def clean_content_count(self, content):
        java_string = 'Evaluation Warning: The document was created with Spire.Doc for JAVA.'
        return len(content.strip().replace(' ', '').replace('\n', '').replace('\r', '').replace(java_string, ''))

    def clean_content(self, content):
        java_string = 'Evaluation Warning: The document was created with Spire.Doc for JAVA.'
        return content.replace(java_string, '')


class DocUploadFormWeb(FileBaseForm):
    file = FileField('file', validators=[FileRequired(message='请选择文件上传'),
                                         FileAllowed(['docx', 'doc'], message='仅允许上传docx,doc格式文件！'),
                                         ])
    content = StringField()
    filePath = StringField()
    char_sum = StringField()
    showfilename = StringField()

    def __init__(self):
        super(DocUploadFormWeb, self).__init__()

    def validate_file(self, field):
        file_name = field.data.filename.replace('+', '')
        timestamp = str(int(datetime.now().timestamp()))
        localPath = DOC_PATH + timestamp + '_' + file_name
        self.filePath.data = localPath
        field.data.save(localPath)
        if '.pdf' in file_name:
            char_sum, content = ParsePDF(timestamp + '_' + file_name)
        else:
            char_sum, content = ParseDoc(timestamp + '_' + file_name)
        self.char_sum.data = self.clean_content_count(content)
        self.content.data = self.clean_content(content)
        if self.content.data == '':
            raise ValidationError('doc文档读取失败，可能文件损坏，请检查后重新上传！')
        if len(self.content.data) < 100:
            raise ValidationError('字数不足100！不可检测')
        if len(self.content.data) > 300000:
            raise ValidationError('单次检测上限30万字，请修改或分批上传')

    def clean_content_count(self, content):
        return count_char_sum(content)

    def clean_content(self, content):
        java_string = 'Evaluation Warning: The document was created with Spire.Doc for JAVA.'
        return content.replace(java_string, '')


class MutilDocUploadForm(FileBaseForm):
    selffiles = FileField('file', validators=[FileRequired(message='请选择文件上传'),
                                              FileAllowed(['docx', 'doc'], message='仅允许上传docx,doc格式文件！'),
                                              ])
    filename = StringField()
    filePath = StringField()
    uid = StringField()

    def validate_selffiles(self, field):
        file_name = field.data.filename.replace('+', '')
        self.filename.data = file_name
        timestamp = str(int(datetime.now().timestamp()))
        localPath = SELFDOC_PATH + timestamp + '_' + file_name
        self.filePath.data = localPath
        field.data.save(localPath)


class ReportSearchForm(SearchForm):
    order_number = StringField()

    def validate_order_number(self, field):
        pattern = '^\d{18,19}'
        res = re.fullmatch(pattern, field.data)
        if not res:
            raise ValidationError('订单号格式不正确,应为18或19位数字!')


class ReportSearchPageForm(Form):
    order_number = StringField()
    limit = IntegerField(validators=[NumberRange(min=1, max=5)], default=5)
    page = IntegerField(validators=[NumberRange(min=1)], default=1)

    def validate_order_number(self, field):
        if field.data:
            pattern = '^\d{18,19}'
            res = re.fullmatch(pattern, field.data)
            if not res:
                raise ValidationError('订单号格式不正确,应为18或19位数字!')
        else:
            raise ValidationError('订单号格式不正确,应为18或19位数字!')


class AigcReportSearchForm(SearchForm):
    order_number = StringField()

    def validate_order_number(self, field):
        pattern = '^\d{18,19}'
        res = re.fullmatch(pattern, field.data)
        if not res:
            raise ValidationError('订单号格式不正确,应为18或19位数字!')
        
class ReduceAigcForm(Form):
    order_number = StringField()
    
    def validate_order_number(self, field):
        data = aigc_order_info.query.filter_by(order_number=field.data).first()
        if data.completed ==0:
            raise ValidationError('请等待aigc检测完成！')

        
class WriterAigcReportSearchForm(SearchForm):
    order_number = StringField()


class MyReportSearchForm(SearchForm):
    order_number = StringField()
    uid = IntegerField()

    def __init__(self, g):
        super(MyReportSearchForm, self).__init__()
        self.uid.data = g.user.uid


class WriterReportSearchForm(SearchForm):
    order_number = StringField()


class DeleteReportForm(Form):
    order_number = StringField()


class ShopForm(Form):
    domain = StringField(default='check')


class UnitForm(Form):
    domain = StringField(default='check')


class WriterOrderNumber(Form):
    order_number = StringField()
    num = IntegerField()
    type = StringField(default='init')


class AutoDealForm(Form):
    reports = FieldList(StringField())


class AIRewriteForm(Form):
    order_number = StringField(default='')
    sentence_index = StringField(default='')
    sentence = StringField(default='')
    current_ai_sentence = StringField(default='')
    
class AIGCRewriteForm(Form):
    sentence = StringField(default='')


class MpQRCodeForm(Form):
    order_number = StringField(default='')

    # def validate_order_number(self, field):
    #     count = AISentence.query.filter_by(order_number=field.data).scalar()
    #     if count > 15:
    #         if field.data[0:2] in ['88', '99']:
    #             pass
    #         else:
    #             pass


class VerifyForm(Form):
    captcha = StringField()
